/**
 * The contents of this file are subject to the license and copyright detailed in the LICENSE and NOTICE files at the root of the source tree and available online at
 * http://www.askosi.org/license.html
 */
package be.destin.skos.core;

import java.util.HashMap;
import java.util.LinkedList;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import org.apache.log4j.Logger;

import be.destin.rdf.changes.Power;

/**
 * @author Christophe Dupriez
 *
 */
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(propOrder={"application","role","browsed","proposed","reviewed","published"})
public class Profile extends Concept {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** log4j category */
	private static Logger log = Logger.getLogger(Profile.class);

	public static final String guest = "guest";
	
    private LinkedList<String>applications;
	private LinkedList<String>roles;
	private LinkedList<String>browsed;
	private LinkedList<String>proposed;
	private LinkedList<String>reviewed;
	private LinkedList<String>published;

	private HashMap<String,Power> schemeMaxPower = null;

	public Profile() {
    	super();
    }

	public Profile(ConceptScheme list) {
    	super(list);
    }

	public static Profile getInstance(SkosManager skosManager,String aName) {
		Profile aConcept = null;
		ConceptScheme aScheme = skosManager.getProfiles();
		if (aScheme != null) {
			aConcept = (Profile) aScheme.getConcept(aName);
		}
		log.debug(aName+", profile="+aConcept);
		return aConcept;
	}

	@XmlTransient
	public LinkedList<String> getDefinedApplicationsList() {
		if (applications == null) {
			return getInScheme().getManagerInstance().getDefinedApplicationsList();
		}
		return applications;
	}

	@XmlTransient
	public LinkedList<String> getDefinedRolesList() {
		if (roles == null) {
			return getInScheme().getManagerInstance().getDefinedRolesList();
		}
		return roles;
	}

	@XmlTransient
	public LinkedList<String> getBrowsedList() {
		LinkedList<String> result = getProposedList();
		if (browsed != null) {
			for (String aScheme: browsed) {
				if (!result.contains(aScheme)) {
					result.add(aScheme); // .add is ALWAYS true !!!
				}
			}
		}
		return result;
	}

	@XmlTransient
	public LinkedList<String> getProposedList() {
		LinkedList<String> result = getReviewedList();
		if (proposed != null) {
			for (String aScheme: proposed) {
				if (!result.contains(aScheme)) {
					result.add(aScheme);
				}
			}
		}
		return result;
	}

	@XmlTransient
	public LinkedList<String> getReviewedList() {
		LinkedList<String> result = getPublishedList();
		if (reviewed != null) {
			for (String aScheme: reviewed) {
				if (!result.contains(aScheme)) {
					result.add(aScheme);
				}
			}
		}
		return result;
	}

	@XmlTransient
	public LinkedList<String> getPublishedList() {
		LinkedList<String> result = getPublished();
		return result;
	}

	@XmlTransient
	public synchronized HashMap<String,Power> getPower() {
		if (schemeMaxPower == null) {
			schemeMaxPower = new HashMap<String,Power>();
			if (browsed != null) {
				for (String aScheme: browsed) {
					schemeMaxPower.put(aScheme,Power.Read);
				}
			}
			if (proposed != null) {
				for (String aScheme: proposed) {
					schemeMaxPower.put(aScheme,Power.Propose);
				}
			}
			if (reviewed != null) {
				for (String aScheme: reviewed) {
					schemeMaxPower.put(aScheme,Power.Review);
				}
			}
			if (published != null) {
				for (String aScheme: published) {
					schemeMaxPower.put(aScheme,Power.Publish);
				}
			}
		}
		return schemeMaxPower;
	}
	
	public Power getPower(String schemeName) {
		return getPower().get(schemeName);
	}

	public boolean hasPower(Power powerNeeded, String schemeName) {
		Power maxPow = getPower(schemeName);
		if (maxPow == null) return false;
		return  maxPow.ordinal() >= powerNeeded.ordinal();
	}

	public LinkedList<String> getApplication() {
		if (applications == null) applications = new LinkedList<String>();
		return applications;
	}

	public void setApplication(LinkedList<String> applications) {
		this.applications = applications;
	}

	public LinkedList<String> getRole() {
		if (roles == null) roles = new LinkedList<String>();
		return roles;
	}

	public void setRole(LinkedList<String> roles) {
		this.roles = roles;
	}

	public LinkedList<String> getBrowsed() {
		if (browsed == null) browsed = new LinkedList<String>();
		return browsed;
	}

	public void setBrowsed(LinkedList<String> browsed) {
		this.browsed = browsed;
	}

	public LinkedList<String> getProposed() {
		if (proposed == null) proposed = new LinkedList<String>();
		return proposed;
	}

	public void setProposed(LinkedList<String> proposed) {
		this.proposed = proposed;
	}

	public LinkedList<String> getReviewed() {
		if (reviewed == null) reviewed = new LinkedList<String>();
		return reviewed;
	}

	public void setReviewed(LinkedList<String> reviewed) {
		this.reviewed = reviewed;
	}

	public LinkedList<String> getPublished() {
		if (published == null) published = new LinkedList<String>();
		return published;
	}

	public void setPublished(LinkedList<String> published) {
		this.published = published;
	}

	public boolean equals(Object o) {
		return super.equals(o);
	}

}
